实现排序算法,时间复杂度为O(n)

我们常用的排序冒泡排序 O(n^2); 快速排序O(nlogn);堆排序O(nlogn);选择排序O(n^2);

我们常用的排序都不符合时间复杂度的要求;

经常听说一个说法  用空间代替时间

现在要排序的数组为数组 a;例如a数组里面有  1,1,2,2,3,3,2,2,5,5.........等等很多无序的数字

那么我们申请一个数组b,假设a数组当中的数字都在100一下;

那么我们的b数组只要申请b【100】就可以了

 

void SortByN(int a[], int length)
{
	if (a == NULL || length < 0)
	{
		return;
	}
	//重新申请一个数组
	const int N =200;
	int b[N];
	//把新申请的数组全部初始化为0
	for (int i = 0; i < N; ++i)
	{
		b[i] = 0;
	}
	//遍历a数组
	for (int i = 0; i < length; ++i)
	{
		//例如:a[0] = 10;那么b[key] = b[10] = 1;表示有一个10; a[4] = 10;
		//那么b[key] = b[10] = 1+1 = 2,表示此时有两个10;
		int key = a[i];
		++b[key];
		//意思就是b数组里面存放的是a数组中某个元素的个数,b[10]表示在a数
		//组当中10出现的次数,b[0]表示0在a数组当中出现的次数
	}
	int index = 0;
	for (int i = 0; i < N; ++i)
	{
		//如果b[0] = 0;表示a数组当中没有0;那么不执行这个循环;例如这里a是一个年龄数组,假设最小的年龄是18
		//那么b[0] -- b[17]都是等于0;那么第二个循环都不执行,第一个循环执行,i加到了18;b[18]=2;
		//那么a数组当中有两个18;而且这两个18就是最小的数字,那么a[0] = 18; a[1] = 18;
		for (int j = 0; j < b[i];++j)
		{
			a[index] = i;
			++index;
		}
	}
}

 

b数组的大小是一个常量,所以遍历b数组的时间复杂度是O(1);

 


完整测试代码:

 

// SortByN.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string.h>
using namespace std;


void SortByN(int a[], int length)
{
	if (a == NULL || length < 0)
	{
		return;
	}

	//重新申请一个数组
	const int N =200;
	int b[N];
	//把新申请的数组全部初始化为0
	for (int i = 0; i < N; ++i)
	{
		b[i] = 0;
	}
	//遍历a数组
	for (int i = 0; i < length; ++i)
	{
		//例如:a[0] = 10;那么b[key] = b[10] = 1;表示有一个10; a[4] = 10;那么b[key] = b[10] = 1+1 = 2,表示此时有两个10;
		int key = a[i];
		++b[key];
		//意思就是b数组里面存放的是a数组中某个元素的个数,b[10]表示在a数组当中10出现的次数,b[0]表示0在a数组当中出现的次数
	}

	int index = 0;
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < b[i];++j)//如果b[0] = 0;表示a数组当中没有0;那么不执行这个循环;例如这里a是一个年龄数组,假设最小的年龄是18
		//那么第一个循环b[0] -- b[17]都是等于0;那么第二个循环都不执行,第一个循环执行,i加到了18;b[18]=2;那么a数组当中有两个18;而且这两个
		//18就是最小的数字,那么a[0] = 18; a[1] = 18;
		{
			a[index] = i;
			++index;
		}
	}



}

int _tmain(int argc, _TCHAR* argv[])
{
	int a[10] = {2,2,3,3,111,111,33,44,55,55};
	for (int i = 0; i < 10; ++i)
	{
		cout<<a[i]<<" ";
	}
	SortByN(a,10);
	cout<<"排序后的数组为:"<<endl;
	for (int i = 0; i < 10; ++i)
	{
		cout<<a[i]<<" ";
	}

	getchar();
	return 0;
}


 

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值